﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;


namespace japanese
{

    enum DisplayColomnInformation
    { 
        HanZi = 2,
        JiaMin = 3,
        YuYi = 4,
        LiJu = 5,

        //从第二行开始
        Beginrow = 2,
    }


    enum KeyButton { 
        Next = 1,  //下一行
        Pre = 2,   //上一行
        Enter = 3,   //当前行
        Refresh = 4, //只刷新
    }


    /// <summary>
    /// 显示的步骤
    /// </summary>
    class NextStep
    {
        static DisplayStep[] JianMinFirstStep = { DisplayStep.JiaMin, 
                                                    DisplayStep.HanZi, 
                                                    DisplayStep.YuYi, 
                                                    DisplayStep.LiJu };
        static DisplayStep[] HanZiFirstStep = { DisplayStep.HanZi,
                                              DisplayStep.JiaMin,
                                              DisplayStep.YuYi,
                                              DisplayStep.LiJu};
        static DisplayStep[] YuYiFirstStep = { 
                                                DisplayStep.YuYi,
                                                DisplayStep.HanZi,
                                                DisplayStep.JiaMin,
                                                DisplayStep.LiJu
                                             };

        int step = 0;
        public NextStep() { step = 0; }
        public void InitStep() { step = 0; }
        public DisplayStep GetNext(LogSettingDisplay style)
        {
            DisplayStep  l;
            
            if (this.step > 3) this.step = 0;
            switch (style)
            {
                case LogSettingDisplay.HanZiFirst:
                    l= HanZiFirstStep[step];
                    break;
                case LogSettingDisplay.JiaMingFirst:
                    l= JianMinFirstStep[step];
                    break;
                    
                case LogSettingDisplay.YuYiFirst:
                    l= YuYiFirstStep[step];
                    break;
                default:
                    step = 0;
                    l = YuYiFirstStep[step];
                    break;
            }
            
            this.step++;
            return l;
        }

        public bool IsBeginning()
        {
            if (this.step >3)
            { return true; }

            return false;
        }

        public DisplayStep GetPre(LogSettingDisplay style)
        {
            if (this.step <0) this.step = 3;
            switch (style)
            {
                case LogSettingDisplay.HanZiFirst:
                    return HanZiFirstStep[step--];
                case LogSettingDisplay.JiaMingFirst:
                    return JianMinFirstStep[step--];
                case LogSettingDisplay.YuYiFirst:
                    return YuYiFirstStep[step--];
                default: return DisplayStep.HanZi;
            }   
        }
    }



    /// <summary>
    /// 刷新ui文本事件参数类
    /// </summary>
    public class TextEventArgs :EventArgs
    {
       public String text;
    }


    /// <summary>
    /// 刷新ui文本事件 委托
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    public delegate void TextDisplayEvent(object sender,TextEventArgs args);


    public class RowChangeEventArgs:EventArgs
    {
        public string filename;
        public int sheetindex;
        public int prerow;
        public int nowrow;

        public RowChangeEventArgs(){}
    }

    public delegate void RowChangeEvent(object sender,RowChangeEventArgs args);


    //显示项
    public class DisplayItem
    {
        public String HanZi = "";
        public String JiaMin = "";
        public String Yuyi = "";
        public String Liju = "";
        public DisplayItem() { }
    }


    //显示驱动引擎
    class DisplayEngine
    {
        ExcelOperation op;
        int sheetindex;
        int rows = (int)DisplayColomnInformation.Beginrow;   // 1 - rowMax
        int rowsMax =10000;

        DisplayItem item = new DisplayItem();
        NextStep steps = new NextStep();

        //显示方案
        LogSettingDisplay display;
        LogSettingMode mode;
        LogSettingTimes times;

        //显示对应的事件
        public event TextDisplayEvent JianMinEvent;
        public event TextDisplayEvent HanZiEvent;
        public event TextDisplayEvent YuLiEvent;
        public event TextDisplayEvent LijuEvent;

        //换行事件
        public event RowChangeEvent RowChange;

        //定时
        private Timer timer = new Timer();


        //属性，必须设置与更改的
        public ExcelOperation CurrentExcel {
            set {
                this.op = value;
            }

            get {
                return this.op;
            }
        }

        public int CurrentSheetIndex {
            set { this.sheetindex = value; }
            get { return this.sheetindex; }
        }

        public int CurrentSheetRows {
            set {
                if (this.rows != value)
                {
                    this.rowChangeFunction(this.rows, value);
                }
                this.rows = value; 
                
            }
            get { return this.rows; }
        }

        public LogSettingDisplay DisplayStyle {
            set { this.display = value; }
            get { return this.display; }
        }

        public LogSettingMode DisplayMode {
            set { this.mode = value; }
            get { return this.mode; }
        }

        public LogSettingTimes DisplayTime {
            set { this.times = value;
            if (this.times != LogSettingTimes.Disable)
            {
                this.timer.Interval = (int)((int)this.times * 1000);
                this.timer.Start();
            }
            else {
                this.timer.Stop();
                }
            }
            get { return this.times; }
        }
        public int RowsMax {
            set { this.rowsMax = value; }
            get { return this.rowsMax; }
        }

        private int RowsRange {
            get { return this.rowsMax + (int)DisplayColomnInformation.Beginrow - 1; }
        }



        private void rowChangeFunction(int pre,int now)
        {
            if (this.RowChange != null)
            {

                RowChangeEventArgs arg = new RowChangeEventArgs();
                arg.filename = this.CurrentExcel.filename;
                arg.prerow = pre;
                arg.nowrow = now;
                arg.sheetindex = this.sheetindex;

                this.RowChange(this, arg);

            }
        }

        /// <summary>
        /// 定时阅读方式 enable 与 disable
        /// </summary>
        public void TimerEnable()
        {
            if (this.times != LogSettingTimes.Disable) { this.timer.Start(); }
        }

        public void TimerDisable()
        {
            this.timer.Stop();
        }



        /// <summary>
        /// 构造函数
        /// </summary>
        public DisplayEngine()
        {
            this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }

        void  timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            this.Refresh(KeyButton.Next);
        }

        /// <summary>
        /// 初始化一次显示
        /// </summary>
       public void DisplayItemInit()
        {
            //初始化步骤
            this.steps.InitStep();

            try
            {
                if (this.op != null)
                {
                    this.item.HanZi = this.op.ReadSheet(this.sheetindex, rows, (int)DisplayColomnInformation.HanZi);
                    this.item.JiaMin = this.op.ReadSheet(this.sheetindex, rows, (int)DisplayColomnInformation.JiaMin);
                    this.item.Yuyi = this.op.ReadSheet(this.sheetindex, rows, (int)DisplayColomnInformation.YuYi);
                    this.item.Liju = this.op.ReadSheet(this.sheetindex, rows, (int)DisplayColomnInformation.LiJu);
                }
            }
            catch {
                Console.WriteLine("无法读取数据:"+ op.filename+"  sheetindex:" + sheetindex + "  rows:"+this.rows);
            }
        }


       public void ClearDisplay()
       { 
           TextEventArgs arg  =new TextEventArgs();
           arg.text = "";
           if (this.HanZiEvent != null) { this.HanZiEvent(this, arg); }
           if (this.JianMinEvent != null) { this.JianMinEvent(this, arg); }
           if (this.YuLiEvent != null) { this.YuLiEvent(this, arg); }
           if (this.LijuEvent != null) { this.LijuEvent(this, arg); }
       }

       private void ReciteNextDisplay()
       {
           //开始时清空文本
           if (this.steps.IsBeginning()) {
               this.ClearDisplay();
           }
           DisplayStep d = this.steps.GetNext(this.display);

           TextEventArgs arg = new TextEventArgs();
           switch (d)
           {
               case DisplayStep.HanZi:
                   arg.text = this.item.HanZi;
                   if (this.HanZiEvent != null)
                   { this.HanZiEvent(this, arg); }
                   break;
               case DisplayStep.JiaMin:
                   arg.text = this.item.JiaMin;
                   if (this.JianMinEvent != null)
                   { this.JianMinEvent(this, arg); }
                   break;
               case DisplayStep.YuYi:
                   arg.text = this.item.Yuyi;
                   if (this.YuLiEvent != null)
                   { this.YuLiEvent(this, arg); }
                   break;
               case DisplayStep.LiJu:
                   arg.text = this.item.Liju;
                   if (this.LijuEvent != null)
                   { this.LijuEvent(this, arg); }
                   break;
           }       
       }


       private void BrouseNextDisplay()
       { 
           TextEventArgs arg = new TextEventArgs();
           if (this.HanZiEvent != null) {
               arg.text = this.item.HanZi;
               this.HanZiEvent(this, arg);
           }

           if (this.JianMinEvent != null)
           {
               arg.text = this.item.JiaMin;
               this.JianMinEvent(this, arg);
           }

           if (this.YuLiEvent != null)
           {
               arg.text = this.item.Yuyi;
               this.YuLiEvent(this, arg);
           }

           if (this.LijuEvent != null)
           {
               arg.text = this.item.Liju;
               this.LijuEvent(this, arg);
           }
       
       }


        /// <summary>
        /// 刷新显示
        /// </summary>
       public void Refresh(KeyButton key)
       {

           switch (key)
           { 
               case KeyButton.Next:
                    
                   if (this.mode == LogSettingMode.RandBrouse || this.mode == LogSettingMode.SequenceBrouse)
                   {
                       this.ClearDisplay(); 
                       this.GetNextItem();
                       this.BrouseNextDisplay();
                   }
                   else{
                       if (this.steps.IsBeginning()) this.GetNextItem();
                        this.ReciteNextDisplay();
                   }
                   break;
               case KeyButton.Enter:
                   if (this.mode == LogSettingMode.RandBrouse || this.mode == LogSettingMode.SequenceBrouse)
                   {
                       this.BrouseNextDisplay();
                   }
                   else{
                       if (this.steps.IsBeginning()) this.GetNextItem();
                        this.ReciteNextDisplay();
                   }
                   break;

               case KeyButton.Pre:
                    this.ClearDisplay();
                    this.GetPreItem();                  
                    if (this.mode == LogSettingMode.RandBrouse || this.mode == LogSettingMode.SequenceBrouse)
                    {this.BrouseNextDisplay();}
                    else {
                        this.ReciteNextDisplay(); 
                    }
                    break;

               case KeyButton.Refresh:
                    this.ClearDisplay();
                   if (this.mode == LogSettingMode.RandBrouse || this.mode == LogSettingMode.SequenceBrouse)
                   {
                       this.BrouseNextDisplay();
                   }
                   else {
                        this.ReciteNextDisplay();
                   }
                   break;

           }     
       }

        /// <summary>
        /// 初始化显示的上一行
        /// </summary>
       private void GetPreItem()
       {
           this.steps.InitStep();
           switch (this.mode)
           { 
               case LogSettingMode.RandBrouse:
               case LogSettingMode.RandRecite:
                   Random r = new Random();
                   int newrow = r.Next(this.RowsRange);
                   if (newrow <= (int)DisplayColomnInformation.Beginrow) newrow = (int)DisplayColomnInformation.Beginrow;
                   this.CurrentSheetRows = newrow;
                   this.DisplayItemInit();
                   break;

               case LogSettingMode.SequenceBrouse:
               case LogSettingMode.SequenceRecite:
                   int nr = this.CurrentSheetRows;
                   nr--;
                   if (nr < (int)DisplayColomnInformation.Beginrow) nr = this.RowsRange;
                   this.CurrentSheetRows = nr;
                   this.DisplayItemInit();
                   break;
           }
       }

        /// <summary>
        /// 初始化显示的下一行
        /// </summary>
       private void GetNextItem()
       {
           this.steps.InitStep();
           switch (this.mode)
           {
               case LogSettingMode.RandBrouse:
               case LogSettingMode.RandRecite:
                   Random r = new Random();
                   int rw1 = r.Next(this.RowsRange);
                   if (rw1 <= 0) rw1 = (int)DisplayColomnInformation.Beginrow;
                   this.CurrentSheetRows = rw1;
                   this.DisplayItemInit();
                   break;

               case LogSettingMode.SequenceBrouse:
               case LogSettingMode.SequenceRecite:
                   int rw2 = this.CurrentSheetRows;
                   rw2++;
                   if (rw2 > this.RowsRange) rw2 = (int)DisplayColomnInformation.Beginrow;
                   this.CurrentSheetRows = rw2;
                   this.DisplayItemInit();
                   break;
           }
       }

    }
}
